import {
  getUserInfo
} from '../util/getUserInfo';

var log = require('../util/log.js')
const ws = require('../util/websocket');
const initRoom = require('../util/enterRoom');
const TAG_NAME = 'VR-ROOM';
let localNetTimer = null;
let loadHtmlTimer = null;
let joinTimeout = null;

Page({
  data: {
    userId: null,
    userSig: null,
    sdkAppId: null,
    roomID: null,
    // 音视频模板
    template: 'custom',
    isErrorModalShow: false, // 房间事件会重复触发，增加错误窗口是否显示的标志
    classUrl: '', // 课堂链接
    loadClass: true, //是否加载音视频
    loadWebview: false,
    videoSize: 150, // 视频的
    trtcConfig: {},
    hint: [], // 缓存提醒框
    flag: false, // 是否写过msg日志
    ifShowVideo: false, // 是否展示视频框
    ifShowShare: false, // 是否展示share按钮
    canIUse: wx.canIUse('button.open-type.getUserInfo'), // 获取用户权限
  },

  /**
   * 页面调整
   */
  onResize() {
    this.showError("页面自适应功能正在建设中，敬请期待");
  },

  /**
   * 页面加载成功
   * @param {*} options 加载参数
   */
  onReady(options) {
    // 保持屏幕常亮
    wx.setKeepScreenOn({
      keepScreenOn: true
    })
  },

  /**
   * 显示时调用
   */
  onShow(options) {
    // 隐藏主按钮
    wx.hideHomeButton();
    log.debug(TAG_NAME, "page show", options)
    log.debug(TAG_NAME, "page data", this.data)
    if (this.data.isShare) {
      this.hideLoad()
      // 开始音视频推拉流
      this.startRTC();
      // 展示音视频框 隐藏分享按钮
      this.setData({
        ifShowVideo: true,
        ifShowShare: false,
      })
    }
  },

  /**
   * 分享小程序给好友
   */
  async onShareAppMessage() {
    this.showLoad()
    this.sendResizeMsgToH5();
    const roomID = this.data.roomID
    const url = `/pages/tic/room_webview/index/index?roomID=${roomID}`
    const imgUrl = this.data.imgUrl;
    this.setData({
      isShare: true
    })
    log.debug(TAG_NAME, "share url====%o", url, this.data.agentName)
    return {
      title: this.data.agentName + '邀请您加入VR会客厅',
      path: url,
      imageUrl: imgUrl + '/homepage/preview.png'
    }
  },

  /**
   * 发送消息到h5 更改页面高度
   */
  sendResizeMsgToH5: function () {
    // 要发送的消息
    const msg = {
      cmd: 'resizeH5'
    }
    // 发送消息
    ws.sendWsMsg(msg);
  },

  /**
   * 获取用户信息
   */
  async bindGetUserInfo() {
    const {
      enterType,
      userId,
      agentId,
      serviceUrl
    } = this.data;
    await getUserInfo(enterType, userId, agentId, serviceUrl);
    this.setData({
      hasUserInfo: true
    })
  },

  /**
   * 获取系统版本
   */
  getSysVersion: function () {
    const sysVersion = wx.getSystemInfoSync().system;
    // 如果是ios系统
    if (sysVersion.indexOf('iOS') > -1) {
      // 拿到系统版本号的第一位
      const sysNum = Number(sysVersion.substring(4).split('.')[0]);
      // 低于iOS 11版本不兼容
      if (sysNum < 11) {
        this.showError("当前系统版本过低,请升级版本后再试");
      }
    } else if (sysVersion.indexOf('Android') > -1) {
      // 拿到系统版本号的第一位
      const sysNum = Number(sysVersion.substring(8).split('.')[0]);
      // 低于Andrios 7版本不兼容
      if (sysNum < 7) {
        this.showError("当前系统版本过低,请升级版本后再试");
      }
    } else {
      this.showError("当前平台功能正在开发中，敬请期待!");
    }
  },

  /**
   * 处理接收到的ws消息
   * @param {*} msg 
   */
  dealReceiveMsg(msg) {
    // 如果视频框不存在 1.若分享按钮存在 需要隐藏 2.若分享按钮不存在 需要显示
    if (!this.data.ifShowVideo) {
      const ifShowShareBtn = this.data.ifShowShare && msg.hide;
      this.setData({
        ifShowShare: !ifShowShareBtn
      })
    }
  },

  /**
   * 加载页面时触发，单页面触发一次
   * @param {*} options 参数
   */
  onLoad: async function (options) {
    // wx.hideShareMenu()
    this.showLoad()
    const version = wx.getAccountInfoSync().miniProgram.envVersion
    if (version !== 'develop') {
      this.getSysVersion();
    }
    log.debug(TAG_NAME, "进入room页面参数", options)
    let params = options;
    if (!options.roomID) {
      // 小程序进入
      const res = await initRoom.enterRoom(options);
      // 创建ws连接
      initRoom.initWebsocket(this.dealReceiveMsg);
      params = res;
    }

    this.setData({
      userId: params.userId || params.openId,
      userSig: params.userSig || params.userSign,
      sdkAppId: params.sdkAppId,
      roomID: params.roomID,
      role: params.role,
      wrapUrl: params.wrapUrl, //包装iframe页面url
      wsUrl: params.wsUrl, //websocket通道url
      debugEnable: params.debugType, //是否开启debug vconsole eruda
      serviceUrl: params.serviceUrl, //后台服务url
      imgUrl: params.imgUrl,
      hasUserInfo: params.hasUserInfo,
      isShare: params.isShare,
      enterType: params.enterType,
      customerId: params.customerId,
      productId: params.productId,
      agentName: params.agentName,
      userToken: params.userToken ? params.userToken : wx.getStorageSync("token"), // 银保获取本地token数据
      agentId: params.agentId ? params.agentId : "YBTEST", // 银保理财经理Id
      exitMode: params.exitMode, // 退出模式
    })

    // if (this.data.enterType === "1") {
    //   // 卡片进入
    //   this.sendResizeMsgToH5();
    // }
    this.callWebview();
    wx.onAppHide(this.destoryPage);
    this.hideLoad();
  },

  /**
   * 触发webview加载h5页面
   */
  callWebview() {
    const {
      wrapUrl,
      roomID,
      userId,
      wsUrl,
      debugEnable,
      role,
      customerId,
      productId,
      userToken,
      agentId,
    } = this.data
    // websocket 方式连接
    let url = `${wrapUrl}?roomId=${roomID}&userId=${userId}&wsUrl=${wsUrl}&HYDEBUG=${debugEnable}&role=${role}&customerId=${customerId}&productId=${productId}&userToken=${userToken}&agentId=${agentId}`;
    log.debug(TAG_NAME, 'classUrl:', url);
    let self = this;
    this.setData({
      classUrl: url,
      loadWebview: true
    }, () => {
      // 加载页面加载监听
      if (!loadHtmlTimer) {
        loadHtmlTimer = setInterval(function () {
          self.showToast('当前网络质量不佳')
        }, 10000)
      }
    });
  },

  /**
   * 开始启动音视频功能
   */
  startRTC() {
    // 获取webrtc组件
    this.setData({
      trtcConfig: {
        sdkAppID: this.data.sdkAppId, // 开通实时音视频服务创建应用后分配的 SDKAppID
        userID: this.data.userId, // 用户 ID，可以由您的帐号系统指定
        userSig: this.data.userSig, // 身份签名，相当于登录密码的作用
        template: this.data.template, // 画面排版模式
        serviceUrl: this.data.serviceUrl, // 后台服务URL
        role: this.data.exitMode, // 角色
      }
    }, () => {
      let trtcRoomContext = this.selectComponent('#trtcroom')
      let timeout = 4000;
      let EVENT = trtcRoomContext.EVENT
      let self = this;
      joinTimeout = setTimeout(function () {
        self.showError('提示', '进房失败，建议在网络较好的情况下重试')
      }, 10000)
      if (trtcRoomContext) {
        // 监听本地用户进房
        trtcRoomContext.on(EVENT.LOCAL_JOIN, (event) => {
          // 进房成功后发布本地音频流和视频流 
          // trtcRoomContext.publishLocalVideo()
          trtcRoomContext.publishLocalAudio()
          this.closeJoinTimer()
          localNetTimer = setInterval(this.checkNat, timeout)
        })

        // 监听本地用户退出房间
        trtcRoomContext.on(EVENT.LOCAL_LEAVE, (event) => {
          // 本地退房
          this.showError('退出当前房间')
        })

        // 监听远端用户进入房间
        trtcRoomContext.on(EVENT.REMOTE_USER_JOIN, (event) => {
          // 提示远端用户进入
          let userID = event.data.userID
          log.debug(TAG_NAME, '用户' + userID + '进入房间[' + this.data.roomID + ']')
          // this.showToast('远端用户进入房间')
          if (this.data.role === '0') {
            this.showToast('客户进入会客厅')
          }
          wx.request({
            url: decodeURIComponent(this.data.serviceUrl) + '/user/query',
            data: {
              userId: userID
            },
            method: 'POST',
            header: {
              'content-type': 'application/json' // 默认值
            },
            success(res) {
              if (res.data.body) {
                //获取用户信息（头像和昵称）
                trtcRoomContext.setData({
                  streamName: decodeURIComponent(res.data.body.userName),
                  streamImage: decodeURIComponent(self.data.serviceUrl) + '/user/image/' + res.data.body.userId
                })
              } else {
                trtcRoomContext.setData({
                  streamName: self.data.role === '0' ? '客户' : '理财经理'
                })
              }
            },
            fail(res) {
              log.debug(TAG_NAME, "获取远端信息异常", res)
              trtcRoomContext.setData({
                streamName: self.data.role === '0' ? '客户' : '理财经理'
              })
            }
          })
        })

        // 监听远端用户离开房间
        trtcRoomContext.on(EVENT.REMOTE_USER_LEAVE, (event) => {
          // 提示远端用户离开
          let userID = event.data.userID
          log.debug(TAG_NAME, '用户' + userID + '离开房间[' + this.data.roomID + ']')
          // this.showToast('远端用户离开房间')
          if (this.data.role === '0') {
            this.showToast('客户已离开会客厅');
            // 远端用户退房，清空用户信息
            trtcRoomContext.setData({
              streamName: null,
              streamImage: null,
              streamAllowVideo: false,
            })
          } else {
            this.showError('会话已结束', '请联系理财经理重新建立', 'error');
          }
        })

        // 监听远端用户的视频流的变更事件
        trtcRoomContext.on(EVENT.REMOTE_VIDEO_ADD, (event) => {
          // 订阅（即播放）远端用户的视频流
          let userID = event.data.userID
          let streamType = event.data.streamType // 'main' or 'aux'   
          trtcRoomContext.subscribeRemoteVideo({
            userID: userID,
            streamType: streamType
          })
          // this.showToast('订阅远端视频流')
        })

        // 监听远端用户的音频流的变更事件
        trtcRoomContext.on(EVENT.REMOTE_VIDEO_REMOVE, (event) => {
          trtcRoomContext.setData({
            streamAllowVideo: false
          })
        })

        // 监听远端用户的音频流的变更事件 
        trtcRoomContext.on(EVENT.REMOTE_AUDIO_ADD, (event) => {
          // 订阅（即播放）远端用户的音频流 
          let userID = event.data.userID
          trtcRoomContext.subscribeRemoteAudio({
            userID: userID
          })
          // this.showToast('订阅远端音频流')    
        })

        // 远端播放状态监控
        trtcRoomContext.on(EVENT.REMOTE_STATE_UPDATE, (event) => {
          if (event.data && event.data.detail) {
            const code = event.data.detail.code
            switch (code) {
              case 2003:
                log.debug(TAG_NAME, '渲染首帧视频', code)
                trtcRoomContext.setData({
                  streamAllowVideo: true
                })
                break
              case 2103:
              case 2104:
              case 2105:
                this.showToast('对方通话质量不佳')
                break;
            }
          }
          // log.debug(TAG_NAME, '远端播放状态', event)
        })

        // 本地播放状态监控
        trtcRoomContext.on(EVENT.LOCAL_STATE_UPDATE, (event) => {
          if (event.data && event.data.code) {
            const code = event.data.code
            switch (code) {
              case 1003:
                log.debug(TAG_NAME, '打开摄像头成功', code)
                break
              case 1007:
                break;
              case 2003:
                log.debug(TAG_NAME, '本地渲染首帧视频', code)
                trtcRoomContext.setData({
                  allowVideo: true
                })
                break
            }
          }
          // log.debug(TAG_NAME, '本端播放状态', event)
        })

        // 远端网络状态监控
        trtcRoomContext.on(EVENT.REMOTE_NET_STATE_UPDATE, (event) => {
          if (event.data && event.data.detail && event.data.detail.info) {
            if (event.data.detail.info.netQualituLevel > 3) {
              this.showToast('对方通话质量不佳')
            }
          }
          // log.debug(TAG_NAME, '远端网络状态', event)
        })

        // 本地网络状态监控
        trtcRoomContext.on(EVENT.LOCAL_NET_STATE_UPDATE, (event) => {
          if (event.data && event.data.detail && event.data.detail.info) {
            if (event.data.detail.info.netQualituLevel > 3) {
              this.showToast('当前通话质量不佳')
            }
          }
          this.closeNetTimer()
          localNetTimer = setInterval(this.checkNat, timeout)
          // log.debug(TAG_NAME, '本地网络状态', event)
        })

        // 异常监听
        trtcRoomContext.on(EVENT.ERROR, (event) => {
          if (event.data) {
            const code = event.data.code
            switch (code) {
              case 10001:
                this.showToast('您禁止了摄像头的使用权限')
                if (trtcRoomContext.data.pusher.enableCamera) {
                  trtcRoomContext._toggleVideo()
                }
                break;
              case 10002:
                this.showToast('您禁止了麦克风的使用权限')
                if (trtcRoomContext.data.pusher.enableMic) {
                  trtcRoomContext._toggleAudio()
                }
                break
              case -1301:
                this.showToast('打开摄像头失败')
                if (trtcRoomContext.data.pusher.enableCamera) {
                  trtcRoomContext._toggleVideo()
                }

                break
              case -1302:
                this.showToast('打开麦克风失败')
                if (trtcRoomContext.data.pusher.enableMic) {
                  trtcRoomContext._toggleAudio()
                }
                break
              case -1303:
              case -1304:
                this.showToast('音视频编解码异常')
                break
              case -100018:
                this.showError('进入房间失败', '请联系理财经理重新建立', error.message);
                break
            }
          }
          log.error(TAG_NAME, '音视频异常', event)
        })

        // 进入房间
        trtcRoomContext.enterRoom({
          roomID: this.data.roomID
        }).catch((error) => {
          log.debug(TAG_NAME, "room joinRoom 进房失败 error====", error)
          self.showError('会话已结束', '请联系理财经理重新建立', error.message);
        })
      }
    })
  },

  /**
   * web页面加载成功时触发
   */
  webviewLoad() {
    // 清除加载页面监听
    this.closeHtmlTimer()
    if (this.data.enterType === 0) {
      // this.setData({
      //   ifShowShare: true
      // })
    } else {
      // 开始音视频推拉流
      this.startRTC();
      this.setData({
        ifShowVideo: true
      })
    }
  },

  /**
   * web页面加载失败
   */
  webviewError() {
    this.showError('打开页面失败')
  },

  /**
   * web页面返回小程序时回调信息
   * @param {*} e 异常信息
   */
  webviewMessage(e) {
    const data = e.detail.data;
    log.debug(TAG_NAME, '页面异常', data)
    this.showError(data[0].msg)
  },

  /**
   * 显示信息弹窗
   * @param {*} msg 
   * @param {*} error 
   */
  showToast(msg) {
    if (this.data.hint.length > 0) {
      this.data.hint.push(msg)
    } else {
      this.data.hint.push(msg)
      this.showToastList()
    }
  },

  /**
   * 递归显示弹窗
   */
  showToastList() {
    let self = this;
    let msg = this.data.hint[0]
    let duration = 2000;
    let timer;
    wx.showToast({
      icon: 'none',
      title: msg,
      duration: duration,
      complete() {
        timer = setTimeout(() => {
          self.data.hint.shift()
          if (self.data.hint.length > 0) {
            self.showToastList()
          }
          clearTimeout(timer)
          timer = ''
        }, duration);
      }
    });
  },

  /**
   * 关闭页面所有信息
   */
  closePage: function () {
    // 关闭websocket
    this.setData({
      classUrl: '',
      loadWebview: false
    })
    this.showError('已退出会客厅');
  },

  /**
   * 关闭HTML定时器检测
   */
  closeHtmlTimer: function () {
    if (loadHtmlTimer) {
      clearInterval(loadHtmlTimer)
      loadHtmlTimer = null;
    }
  },

  /**
   * 关闭webRtc定时器检测
   */
  closeNetTimer: function () {
    if (localNetTimer) {
      clearInterval(localNetTimer)
      localNetTimer = null;
    }
  },

  /**
   * 关闭webRtc定时器检测
   */
  closeJoinTimer: function () {
    if (joinTimeout) {
      clearTimeout(joinTimeout)
      joinTimeout = null;
    }
  },

  /**
   * 小程序隐藏时触发
   * 清除音视频通话并跳转至VR功能引导页面
   */
  destoryPage: function () {
    let that = this;
    this.closeHtmlTimer()
    this.closeNetTimer()
    this.closeJoinTimer()
    this.data.hint.length = 0;
    let trtcRoomContext = this.selectComponent('#trtcroom');
    // 展示音视频框后 hide销毁
    if (trtcRoomContext && this.data.ifShowVideo) {
      trtcRoomContext.unpublishLocalAudio();
      trtcRoomContext.unpublishLocalVideo();
      // 销毁pusher组件
      trtcRoomContext.setData({
        isActive: false
      }, () => {
        that.closePage()
      })
    } else if (!this.data.isShare) {
      this.closePage()
    }
  },

  /**
   * 校验网络
   */
  checkNat() {
    this.showToast('当前通话质量不佳')
  },

  /**
   * 统一错误处理
   * @param {*} msg 
   * @param {*} toolMsg
   * @param {*} error 
   */
  showError(msg, toolMsg, error) {
    log.error(TAG_NAME, 'Error msg:', msg || error);
    wx.redirectTo({
      url: '/pages/tic/room_webview/index/index?type=hangup&exitMode=' + this.data.exitMode + '&msg=' + msg + '&toolMsg=' + toolMsg,
    })
  },

  /**
   * 显示加载框
   */
  showLoad() {
    if (!this.data.isLoading) {
      wx.showLoading({
        title: '加载中'
      })
      this.setData({
        isLoading: true
      })
      log.debug(TAG_NAME, '显示loading框')
    }
  },

  /**
   * 隐藏加载框
   */
  hideLoad() {
    if (this.data.isLoading) {
      wx.hideLoading()
      this.setData({
        isLoading: false
      })
      log.debug(TAG_NAME, '关闭loading框')
    }
  },

  /**
   * 关闭页面
   */
  onUnload: function () {
    this.closeHtmlTimer();
    this.closeNetTimer();
    this.closeJoinTimer();
    // 离开页面时关闭ws连接
    ws.closeWs("room");
    log.debug(TAG_NAME, 'onUnload');
    // 关闭当前页面监听
    wx.offAppHide(this.destoryPage);
    this.setData({
      classUrl: '',
      loadWebview: false
    })
  }
})